package com.xuecheng.content.jobHandler;

import com.xuecheng.base.exception.BusinessException;
import com.xuecheng.base.exception.CommonError;
import com.xuecheng.content.feignclient.CourseIndex;
import com.xuecheng.content.feignclient.MediaServiceClient;
import com.xuecheng.content.feignclient.SearchServiceClient;
import com.xuecheng.content.model.dto.CoursePreviewDto;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.content.service.CoursePublishService;
import com.xuecheng.messagesdk.model.po.MqMessage;
import com.xuecheng.messagesdk.service.MessageProcessAbstract;
import com.xuecheng.messagesdk.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;

/**
 * 课程发布任务处理
 * @author Mdd
 * @Github <a href="https://github.com/mdd123cc"/>
 * @Gitee <a href="https://gitee.com/mdd115192"/>
 */
@Slf4j
@Component
public class CoursePublishTask extends MessageProcessAbstract {


    @Resource
    private CoursePublishService coursePublishService;

    @Resource
    private SearchServiceClient searchServiceClient;


    //任务调度入口
    @XxlJob("CoursePublishJobHandler")
    public void coursePublishJobHandler() throws Exception {
        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        log.debug("shardIndex="+shardIndex+",shardTotal="+shardTotal);
        //参数:分片序号、分片总数、消息类型、一次最多取到的任务数量、一次任务调度执行的超时时间
        process(shardIndex,shardTotal,"course_publish",30,60);
    }


    @Override
    public boolean execute(MqMessage mqMessage) {
        long courseId = Long.parseLong(mqMessage.getBusinessKey1());
        //课程静态化上传minio
        generateCourseHtml(mqMessage,courseId);
        //课程索引添加至es
        saveCourseIndex(mqMessage,courseId);
        //课程信息缓存至redis
        saveCourseCache(mqMessage,courseId);
        return true;
    }

    /**
     * 生成课程静态化页面并上传至文件系统
     * @param mqMessage
     * @param courseId
     */
    public void generateCourseHtml(MqMessage mqMessage, long courseId) {
        Long id = mqMessage.getId();
        MqMessageService mqMessageService = getMqMessageService();
        //消息幂等性处理
        int stageOne = mqMessageService.getStageOne(id);
        if (stageOne > 0) {
            //说明此过程已执行
            log.debug("该消息已生成课程静态化页面");
        }
        //执行逻辑
        //生成课程HTML文件
        File file = coursePublishService.generateCourseHtml(courseId);
        if (file==null){
            throw new BusinessException("生成课程静态文件失败");
        }
        //上传至minio
        coursePublishService.uploadCourseHtml(courseId,file);
        //完成该过程,更新状态
        mqMessageService.completedStageOne(courseId);
    }

    /**
     * 将课程信息缓存至redis
     * @param mqMessage
     * @param courseId
     */
    public void saveCourseCache(MqMessage mqMessage, long courseId) {
        Long id = mqMessage.getId();
        MqMessageService mqMessageService = getMqMessageService();
        //消息幂等性处理
        int stageTwo = mqMessageService.getStageTwo(id);
        if (stageTwo > 0) {
            //说明此过程已执行
            log.debug("课程信息已缓存至redis");
        }
        //执行逻辑
        //完成该过程,更新状态
        mqMessageService.completedStageTwo(courseId);
    }

    /**
     * 保存课程索引信息
     * @param mqMessage
     * @param courseId
     */
    public void saveCourseIndex(MqMessage mqMessage, long courseId) {
        Long id = mqMessage.getId();
        MqMessageService mqMessageService = getMqMessageService();
        //消息幂等性处理
        int stageThree = mqMessageService.getStageThree(id);
        if (stageThree > 0) {
            //说明此过程已执行
            log.debug("已保存课程索引信息");
        }
        // 执行逻辑
        //查询课程信息
        CoursePublish coursePublishInfo = coursePublishService.getById(courseId);
        //添加索引到es
        CourseIndex courseIndex = new CourseIndex();
        BeanUtils.copyProperties(coursePublishInfo,courseIndex);
        Boolean res = searchServiceClient.add(courseIndex);
        if (!res) {
            BusinessException.cast("索引添加失败！");
        }

        //完成该过程,更新状态
        mqMessageService.completedStageThree(courseId);
    }


}
